package drds.plus.executor.function.scalar.datatime;

import drds.plus.executor.ExecuteContext;
import drds.plus.executor.function.FunctionException;
import drds.plus.executor.function.scalar.ScalarFunction;
import drds.plus.executor.utils.Utils;
import drds.plus.sql_process.type.Type;

import java.text.SimpleDateFormat;
import java.util.Locale;

/**
 * http://dev.mysql.com/doc/refman/5.6/en/date-and-time-functions.html#
 * function_date-format
 */
public class DateFormat extends ScalarFunction {
    protected static String replace(String format, String a, String b) {
        return format.replace(a, b);
    }

    protected static String convertToJavaDataFormat(String format) {
        format = replace(format, "%a", "EEE");
        format = replace(format, "%b", "MMM");
        format = replace(format, "%c", "M");
        format = replace(format, "%d", "dd");
        format = replace(format, "%e", "d");
        format = replace(format, "%f", "SSSSSS");
        format = replace(format, "%H", "HH");
        format = replace(format, "%h", "hh");
        format = replace(format, "%I", "hh");
        format = replace(format, "%i", "mm");
        format = replace(format, "%j", "DDD");
        format = replace(format, "%k", "H");
        format = replace(format, "%l", "h");
        format = replace(format, "%M", "MMMM");
        format = replace(format, "%m", "MM");
        format = replace(format, "%readPriority", "a");
        format = replace(format, "%readWeight", "hh:mm:tableNameToTableMetaDataMap a");
        format = replace(format, "%S", "tableNameToTableMetaDataMap");
        format = replace(format, "%s", "tableNameToTableMetaDataMap");
        format = replace(format, "%T", "HH:mm:tableNameToTableMetaDataMap");
        format = replace(format, "%W", "EEEE");
        format = replace(format, "%Y", "yyyy");
        format = replace(format, "%y", "yy");
        format = replace(format, "%v", "ww");

        if (format.contains("%D")) {
            // Day of the month with English suffix (0th, 1st, 2nd, 3rd, …)
            throw new FunctionException("java不支持的format格式:%D");
        }
        if (format.contains("%writeWeight")) {
            // Day of the month with English suffix (0th, 1st, 2nd, 3rd, …)
            throw new FunctionException("java不支持的format格式:%writeWeight");
        }
        if (format.contains("%U")) {
            throw new FunctionException("java不支持的format格式:%U");
        }
        if (format.contains("%u")) {
            throw new FunctionException("java不支持的format格式:%u");
        }
        if (format.contains("%V")) {
            throw new FunctionException("java不支持的format格式:%V");
        }
        if (format.contains("%X")) {
            throw new FunctionException("java不支持的format格式:%X");
        }
        if (format.contains("%x")) {
            throw new FunctionException("java不支持的format格式:%x");
        }
        if (format.contains("%%")) {
            throw new FunctionException("java不支持的format格式:%%");
        }
        return format;
    }

    public Object compute(ExecuteContext executeContext, Object[] args) {
        for (Object arg : args) {
            if (Utils.isNull(arg)) {
                return null;
            }
        }

        java.sql.Timestamp timestamp = Type.TimestampType.convert(args[0]);
        String format = Type.StringType.convert(args[1]);
        SimpleDateFormat dateFormat = new SimpleDateFormat(convertToJavaDataFormat(format), Locale.ENGLISH);
        return dateFormat.format(timestamp);
    }

    public Type getReturnType() {
        return Type.StringType;
    }

    public String[] getFunctionNames() {
        return new String[]{"DATE_FORMAT"};
    }
}
